package com.misboot.document.controller;


import cn.ewsd.common.utils.StringUtils;
import com.github.tobato.fastdfs.domain.fdfs.FileInfo;
import com.misboot.document.model.DfsFile;
import com.misboot.document.service.DfsFileService;
import com.misboot.document.utils.FastDFSClient;
import com.misboot.document.utils.file.FileUtils;
import com.misboot.document.utils.minio.MinioUtil;
import io.minio.ObjectWriteResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Api(tags = {"分布式文件FDFS"})
@Controller
@RequestMapping("/fdfs")
public class FastDFSsController extends DocumentBaseController {

    private static Logger logger = LoggerFactory.getLogger(FastDFSsController.class);

    @Autowired
    private DfsFileService dfsFileService;

    @Autowired
    private FastDFSClient fdfsClient;

    @Value("${fdfs.address}")
    String fdfsAddress;



    @Autowired
    MinioUtil minioUtil;

    //地址
    @Value("${minio.url}")
    private String url;

    @ApiOperation(value = "文件上传", notes = "文件上传")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "files", value = "文件，", paramType = "formData", allowMultiple = true, required = true, dataType = "file"),
    })
    @ResponseBody
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public Map<String, Object> upload(MultipartFile file, String puuid) throws Exception {
        String url = fdfsClient.uploadFile(file);
        Map<String, Object> result = new HashMap<>();
        result.put("statusCode", 200);
        result.put("msg", "上传成功");
        result.put("url", fdfsAddress+"/"+url);

        DfsFile dfsFile = new DfsFile();
        dfsFile.setFileName(file.getOriginalFilename());
        dfsFile.setCreatorId(getCurrentUserNameId());
        dfsFile.setCreator(getCurrentUserName());
        dfsFile.setUrl(fdfsAddress+"/"+url);
        dfsFile.setPuuid(puuid);

        //上传文件同名文件版本加1
        List<DfsFile> list = dfsFileService.getMaxVersionByFileName(file.getOriginalFilename());
        if (null != list && !list.isEmpty()) {
            dfsFile.setVersion((String.valueOf(Integer.parseInt(list.get(0).getVersion()) + 1)));
        }


        //long Size = (file.getSize()) / 1024;
        //String fileSize = Size + "KB";
        dfsFile.setFileSize(FileUtils.getSize(file.getSize()));
        dfsFileService.insertSelective(getSaveData(dfsFile));

        return result;
    }


    /**
     * 上传文件人力资源文件 协同办公 调用accessory附件主键
     * @param objectName 保存在存储桶的文件 images/a.doc
     * @param file       文件流
     * @return 文件保存位置
     */
    @ApiOperation("上传一个文件")
    @RequestMapping(value = "/uploadfile", method = RequestMethod.POST)
    @ResponseBody
    public Object fileupload(@RequestParam MultipartFile file, @RequestParam(required = false) String objectName, @RequestParam(required = false) String puuid) throws Exception {
        //上传文件同名，文件名特殊处理
        String fileName = "";
        List<DfsFile> list = dfsFileService.getMaxVersionByFileName(file.getOriginalFilename());
        if (null != list && !list.isEmpty()) {
            Date d = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            fileName = sdf.format(d) + "-" + file.getOriginalFilename();
        } else {
            fileName = file.getOriginalFilename();
        }
        if (StringUtils.isNullOrEmpty(objectName)) {
            objectName = fileName;
        } else {
            objectName = objectName + "/" + fileName;
        }
        ObjectWriteResponse objectWriteResponse = minioUtil.uploadFile(file.getInputStream(), "vue-hr", objectName);
        DfsFile dfsFile = new DfsFile();
        dfsFile.setFileName(fileName);
        dfsFile.setCreatorId(getCurrentUserNameId());
        dfsFile.setCreator(getCurrentUserName());
        dfsFile.setUrl(url  + "vue-accessory/" + objectWriteResponse.object());
        dfsFile.setPuuid(puuid);
        dfsFile.setFileSize(FileUtils.getSize(file.getSize()));
        dfsFileService.insertSelective(getSaveData(dfsFile));

        HashMap var3 = new HashMap();
        var3.put("statusCode", 200);
        var3.put("title", "上传文件成功");
        var3.put("message", "上传文件成功");
        var3.put("bucket", objectWriteResponse.bucket());
        var3.put("object", objectWriteResponse.object());
        var3.put("url", url + "vue-accessory/" + objectWriteResponse.object());
        var3.put("message", "上传文件成功");
        return var3;
    }

    /**
     * 下载一个文件人力资源文件
     * @param objectName 保存在存储桶的文件 images/a.doc
     * @return 文件保存位置
     */
    @ApiOperation("下载一个文件")
    @RequestMapping(value = "/downloadFile", method = RequestMethod.GET)
    public void downloadFile(String objectName,
                             HttpServletResponse response) throws Exception {
        InputStream stream = minioUtil.download("vue-hr", objectName);
        ServletOutputStream output = response.getOutputStream();
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(objectName.substring(objectName.lastIndexOf("/") + 1), "UTF-8"));
        response.setContentType("application/octet-stream");
        response.setCharacterEncoding("UTF-8");
        IOUtils.copy(stream, output);
    }


    /**
     * @MethodName delete
     * @Description http://localhost:9775/fastdfs/fdfs/delete?fileUrl=group1/M00/00/00/wKgBy1xJk6-AdHJsAACiJGgytIc060.png
     * @Param fileUrl
     * @Date 2019/2/17 15:53
     */
    @RequestMapping(value = "/deleteFile", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "文件删除接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "fileUrl", value = "文件地址", required = true, dataType = "String"),
            @ApiImplicitParam(name = "uuid", value = "标识", required = true, dataType = "String"),
            @ApiImplicitParam(name = "fileName", value = "文件名称", required = false, dataType = "String")
    })
    public Object deleteFile(String uuid) {
        try {
            DfsFile dfsFile = dfsFileService.selectByPrimaryKey(uuid);
            minioUtil.deleteObject("vue-hr", dfsFile.getFileName());
            dfsFileService.executeDelete(uuid);
            return success("删除成功！");
        } catch (Exception e) {
            return failure("删除失败！");
        }
    }


    /**
     * 文件下载
     *
     * @param fileUrl  url 开头从组名开始
     *                 http://localhost:9771/fastdfs/fdfs/download?fileUrl=group1/M00/00/00/wKgBy1xJjwSAB47iAACiJGgytIc994.png
     * @param response
     * @throws Exception
     */
    @RequestMapping(value = "/download", method = RequestMethod.GET)
    @ApiOperation(value = "文件下载接口")
    public void download(String fileUrl, String fileName, HttpServletResponse response) throws Exception {
        byte[] data = fdfsClient.download(fileUrl);
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        // 写出
        ServletOutputStream outputStream = response.getOutputStream();
        IOUtils.write(data, outputStream);
    }

    /**
     * @MethodName delete
     * @Description http://localhost:9775/fastdfs/fdfs/delete?fileUrl=group1/M00/00/00/wKgBy1xJk6-AdHJsAACiJGgytIc060.png
     * @Param fileUrl
     * @Date 2019/2/17 15:53
     */
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "文件删除接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "fileUrl", value = "文件地址", required = true, dataType = "String"),
            @ApiImplicitParam(name = "uuid", value = "标识", required = true, dataType = "String"),
            @ApiImplicitParam(name = "fileName", value = "文件名称", required = false, dataType = "String")
    })
    public Object delete(String fileUrl, String uuid, String fileName) {
        try {
            fdfsClient.deleteFile(fileUrl);
            dfsFileService.executeDelete(uuid);
            return success("删除成功！");
        } catch (Exception e) {
            return failure("删除失败！");
        }
    }

    @ResponseBody
    @RequestMapping("/getFileInfo")
    public FileInfo getFileInfo(String groupName, String path) throws Exception {
        FileInfo fileInfo = fdfsClient.getFileInfo(groupName, path);
        return fileInfo;
    }

    /*@PostMapping("/upload")
    @ResponseBody
    public Map<String, String> upload2(@RequestParam("file") MultipartFile file) {
        Map<String, String> map = new HashMap<>();
        if (file.isEmpty()) {
            map.put("status", String.valueOf(300));
            map.put("message", "请选择需要上传的文件");
        }

        try {
            map.put("status", String.valueOf(200));
            map.put("filePath", save(file));
            map.put("fileName", file.getOriginalFilename());
            map.put("creatorUuid", getCurrentUuid());
            map.put("creator", getCurrentUserName());
            map.put("createTime", String.valueOf(new Date()));
        } catch (Exception e) {
            //logger.error("upload file failed", e);
            map.put("status", String.valueOf(300));
            map.put("message", e.getMessage());
        }
        return map;
    }

    *//**
     * @param multipartFile
     * @return
     * @throws IOException
     *//*
    public String save(MultipartFile multipartFile) throws IOException {
        String[] fileAbsolutePath = {};
        String fileName = multipartFile.getOriginalFilename();
        String ext = fileName.substring(fileName.lastIndexOf(".") + 1);
        byte[] file_buff = null;
        InputStream inputStream = multipartFile.getInputStream();
        if (inputStream != null) {
            int len1 = inputStream.available();
            file_buff = new byte[len1];
            inputStream.read(file_buff);
        }
        inputStream.close();
        FastDFSFile file = new FastDFSFile(fileName, file_buff, ext);
        try {
            fileAbsolutePath = fdfsClient.uploadFile(file);  //upload to fastdfs
        } catch (Exception e) {
            logger.error("upload file Exception!", e);
        }
        if (fileAbsolutePath == null) {
            logger.error("upload file failed,please upload again!");
        }
        String path = fdfsClient.getTrackerUrl() + fileAbsolutePath[0] + "/" + fileAbsolutePath[1];
        return path;
    }

    @PostMapping("/delete")
    @ResponseBody
    public Map<String, String> delete() {
        Map<String, String> map = new HashMap<>();
        try {
            map.put("status", String.valueOf(200));
            map.put("message", "删除成功！");
        } catch (Exception e) {
            //logger.error("upload file failed", e);
            map.put("status", String.valueOf(300));
            map.put("message", e.getMessage());
        }
        return map;
    }*/

}
